package errors

import (
	"fmt"
	"strings"
)

// Error 结构体定义
type Error struct {
	Type    string            // 错误类型
	Message string            // 错误信息
	Code    int               // 错误码
	Cause   error             // 原始错误
	Context map[string]string // 错误上下文
}

// 实现error接口
func (e *Error) Error() string {
	var parts []string

	// 添加错误类型和消息
	parts = append(parts, fmt.Sprintf("[%s] %s", e.Type, e.Message))

	// 添加错误码和建议
	if e.Code != 0 {
		parts = append(parts, fmt.Sprintf("错误码: %d", e.Code))
		if suggestion := GetErrorSuggestion(e.Code); suggestion != "" {
			parts = append(parts, fmt.Sprintf("建议: %s", suggestion))
		}
	}

	// 添加上下文信息
	if len(e.Context) > 0 {
		var contextParts []string
		for k, v := range e.Context {
			contextParts = append(contextParts, fmt.Sprintf("%s=%s", k, v))
		}
		parts = append(parts, fmt.Sprintf("上下文: {%s}", strings.Join(contextParts, ", ")))
	}

	// 添加原始错误
	if e.Cause != nil {
		parts = append(parts, fmt.Sprintf("原因: %v", e.Cause))
	}

	return strings.Join(parts, " | ")
}

// 创建新错误
func New(errType, message string) error {
	return &Error{
		Type:    errType,
		Message: message,
		Context: make(map[string]string),
	}
}

// 包装错误
func Wrap(err error, errType, message string) error {
	return &Error{
		Type:    errType,
		Message: message,
		Cause:   err,
		Context: make(map[string]string),
	}
}

// 添加错误上下文
func WithContext(err error, key, value string) error {
	if e, ok := err.(*Error); ok {
		e.Context[key] = value
		return e
	}
	return &Error{
		Type:    ErrSystem,
		Message: err.Error(),
		Context: map[string]string{key: value},
	}
}

// 获取错误类型
func GetType(err error) string {
	if e, ok := err.(*Error); ok {
		return e.Type
	}
	return ErrSystem
}

// 获取原始错误
func Unwrap(err error) error {
	if e, ok := err.(*Error); ok {
		return e.Cause
	}
	return err
}

// 获取错误上下文
func GetContext(err error) map[string]string {
	if e, ok := err.(*Error); ok {
		return e.Context
	}
	return nil
}

// 判断错误类型
func Is(err error, errType string) bool {
	return GetType(err) == errType
}

// 创建系统错误
func NewSystemError(message string) error {
	return NewErrorWithCode(ErrCodeSystem, message)
}

// 创建配置错误
func NewConfigError(message string) error {
	return NewErrorWithCode(ErrCodeConfig, message)
}

// 创建Git错误
func NewGitError(message string) error {
	return NewErrorWithCode(ErrCodeGit, message)
}

// 创建构建错误
func NewBuildError(message string) error {
	return NewErrorWithCode(ErrCodeBuild, message)
}

// 创建Docker错误
func NewDockerError(message string) error {
	return NewErrorWithCode(ErrCodeDocker, message)
}

// 创建部署错误
func NewDeployError(message string) error {
	return NewErrorWithCode(ErrCodeDeploy, message)
}

// 创建健康检查错误
func NewHealthError(message string) error {
	return NewErrorWithCode(ErrCodeHealth, message)
}

// 包装系统错误
func WrapSystemError(err error, message string) error {
	return WrapErrorWithCode(err, ErrCodeSystem, message)
}

// 包装配置错误
func WrapConfigError(err error, message string) error {
	return WrapErrorWithCode(err, ErrCodeConfig, message)
}

// 包装Git错误
func WrapGitError(err error, message string) error {
	return WrapErrorWithCode(err, ErrCodeGit, message)
}

// 包装构建错误
func WrapBuildError(err error, message string) error {
	return WrapErrorWithCode(err, ErrCodeBuild, message)
}

// 包装Docker错误
func WrapDockerError(err error, message string) error {
	return WrapErrorWithCode(err, ErrCodeDocker, message)
}

// 包装部署错误
func WrapDeployError(err error, message string) error {
	return WrapErrorWithCode(err, ErrCodeDeploy, message)
}

// 包装健康检查错误
func WrapHealthError(err error, message string) error {
	return WrapErrorWithCode(err, ErrCodeHealth, message)
}

// 格式化错误信息
func FormatError(err error) string {
	if e, ok := err.(*Error); ok {
		return e.Error()
	}
	return err.Error()
}

// 获取完整错误信息（包括建议）
func GetFullErrorMessage(err error) string {
	if e, ok := err.(*Error); ok {
		msg := e.Error()
		if suggestion := GetErrorSuggestion(e.Code); suggestion != "" {
			msg += fmt.Sprintf("\n建议: %s", suggestion)
		}
		return msg
	}
	return err.Error()
}
